$(document).ready(function(){
	
	// Cards holded by human
	var human = [];
	// Cards holded by computer.
	var computer = [];
	// Cards which can be used to attack.
	var cardsAttackable = [];
	// Cards which can be used to defend
	var cardsDefendable = [];
	// Number of rounds happened.
	var rounds = 0;

	// Positions
	var cardsLeft = 120;
	var cardsTop = 200;
	
	var masterSuit = 0;

	// Position.
	var desk = [ { left: 10, top : 40 }, { left: 20, top : 10 } ];
	
	// status of human
	var humanAttack = false;
	
	// for debug
	var showCard = false;
	
	// create new game
	 $.ajax({
         url : "/durak/new",
     type: "POST",
     dataType : "json",
     data : { format: "json"},
     success: function ( data ) {
             	for(var i = 1; i <= data; i++)
           		{
             		var currentLeft = cardsLeft - (i-1)*2;
             		var currentTop = cardsTop - (i-1)*2;
             		var card = createCard(0x11, false);
             		card.css({"left": currentLeft+'px','top':currentTop+'px'}).appendTo('#cards');
           		}
     		}
	 });

	 // human-machine button.
	 $('#start').click(function(){ start(0); });
	 
	 // machine-machine button.
	 $('#auto').click(function(){ start(1); });	 
	 
	 // attack/defend manually
	 $('#humanPlayer').on('click', 'div.templateCard', function(){
		  	var card = parseInt(this.id);
		  	var index = $.inArray(card, human );
	 		if ( index < 0 ) 
 			{
	 		   alert('Can not find card:' + card);	
	 		   return;
 			}
	 		
	 		if ( humanAttack && $.inArray(card,cardsAttackable) < 0 )
 			{
	 		   alert('Can not attack:' + card);	
	 		   return;
 			}

	 		if ( ! humanAttack && $.inArray(card,cardsDefendable) < 0 )
 			{
	 		   alert('Can not defend:' + card);	
	 		   return;
 			}
	 		
	 		human.splice(index, 1);
	 		$('#'+card).remove();
	 		
	 		
	 		var newCard = createCard(card, true);
	 		var left = desk[0].left + (rounds) * 90;
	 		newCard.css({"left":left+'px' ,'top':desk[0].top+'px'}).appendTo('#desk');

	 		if (humanAttack) 
 			{
	 			 $.ajax({
	 		         url : "/durak/attack",
		 		     type: "POST",
		 		     dataType : "json",
		 		     data : { attacker: 0 ,attackCard: card},
		 		     success: function (data){ 
		 		    	 tryDefend(1, card); 
		 		    	 }
	 			 });
 			}
	 		else 
 			{
	 			 $.ajax({
	 		         url : "/durak/defend",
		 		     type: "POST",
		 		     dataType : "json",
		 		     data : { defender: 0, defendCard: card},
		 		     success: function (data){
		 		    	 rounds = data.rounds;
		 		    	 tryAttack(1); 
	 		    	 }
	 			 });
 			}
	 		return;
	 });
	 
	 
	 $('#endAttack').click(function(){
		 endAttack(0);
	 });
	 
	 $('#accept').click(function(){
		 accept(0);
	 });
	 
	 //----------------------------------------------------------
	 function start( auto )
	 {
		 $.ajax({
	         url : "/durak/start",
	     type: "POST",
	     dataType : "json",
	     data : { auto: auto},
	     success: function ( data ) {
	    	 	var masterSuitLeft = cardsLeft + 50;
	    	 	var masterSuitTop = cardsTop ;
	    	 	var masterCard = createCard(data.masterSuit, true);
	    	 	
	    	 	masterCard.css({"left": masterSuitLeft+'px','top':masterSuitTop+'px',"z-index":-1}).appendTo('#cards');
	    	 	$("#cards .hiddenCard:last").remove();
	    	 	$(".button").hide();
	    	 	masterSuit = data.masterSuit & 0xF0;
	    		updateCards( human, 10, 30, '#humanPlayer', data.humanByValue, data.humanBySuit, true,true);
	    		updateCards( computer, 10, 30, '#computerPlayer', data.computerByValue, data.computerBySuit, showCard,true);
	    		tryAttack(data.attacker);
     		 }
		 });
	 }
	 // the value contains suit and value.
	 function createCard( value, show )
	 {
		 var card = null;
		 if (show )
		 {
			 var suit = value >> 4;
			 value = value & 0x0F;
			 if ( value > 13 ) value = 1;
			 
			 var left =  ( value -1) * 73 +1 ;
			 var top = (suit-1)*98+1;
			 
			 card = $("<div class='templateCard'></div>").css({'background-position':(-left)+"px "+(-top)+"px"});
		 }
		 else
		 {
			 card = $("<div class='hiddenCard'></div>");
		 }
		 return card;
	 }
	 
	 /*  (i-1)*73+1
	    (j-1)*98+1 
	*/
	 
	 /**
	  *  Update Cards hold by player
	  *  curCards :  The cards before updated
	  *  left :  The left of player's position
	  *  top :   The top of player's position
	  *  divID:  The Div ID of player's area
	  *  newCardsByValue : the new cards the player holds.
	  *  newCardsBySuit  : the new cards the player holds.
	  *  show :  The card show its value or not
	  *  remove : Get/accept the cards. 
	  */
	 function updateCards( curCards, left, top, divID, newCardsByValue,newCardsBySuit, show, remove)
	 {
		 // find all cards we need to get.
		 var news = [];
		 for( var p in newCardsByValue)
		 {
			 for ( var i=0; i < newCardsByValue[p].length; i++ ) 
			 {
				 var card = parseInt(p) + parseInt(newCardsByValue[p][i]);
				 if ( $.inArray(card, curCards) < 0 ) news.push(card);
			 }
		 }
		 if ( news.length == 0 ) return curCards;

		 // update curCards.
		 for(var i=0; i < news.length; i++)
		 {
			 curCards.push(news[i]);
    	 	 if (remove) 
   	 		 {
    	 		 lastCard = $("#cards .hiddenCard:last").remove();
    	 		 if (lastCard.length == 0 ) $('#cards .templateCard').fadeTo('fast',0.5);
   	 		 }
		 }
		 
		 $(divID).empty();
		 var cards = [];
		 // Display master suit card.
		 for( var suit in newCardsBySuit)
		 {
			 var index = parseInt(suit);
			 if ( index != masterSuit ) continue;
			 for( var i= newCardsBySuit[suit].length-1; i>=0; i-- ) cards.push(index+newCardsBySuit[suit][i]);
		 }

		 // And then non master-suit card		 
		 for( var suit in newCardsBySuit)
		 {
			 var index = parseInt(suit);
			 if ( index == masterSuit ) continue;
			 for( var i= newCardsBySuit[suit].length-1; i>=0; i-- ) cards.push(index+newCardsBySuit[suit][i]);
		 }
		 
		 // Show cards
		 for(var i=0; i < cards.length; i++)
		 {
			 card = createCard(cards[i],show);
			 var cardleft = left + i*30;
			 card.css({"left": cardleft+'px','top':top+'px'}).attr({id:cards[i]}).appendTo(divID);
			 if ( show ) card.hover(function(){$(this).css({'top':(top-10)+'px'});},function(){$(this).css({'top':(top)+'px'});});
		 }
		 return curCards;
	 }
	 
	 function tryAttack(attacker)
	 {
   		 $.ajax({
	         url : "/durak/tryAttack",
		     type: "POST",
		     dataType : "json",
		     data : { attacker: attacker },
		     success: function ( card ) {
		    	
		    	if ( card.done )
	    		{
		    		alert(card.msg);
		    		document.location.reload();
	    		}
	    	 	if ( card.attackCard > 0 )
    	 		{ // attack automatically
	    	 		var players = [human, computer];			    	 		
	    	 		var cards = players[attacker];
	    	 		var index = $.inArray(card.attackCard, cards );
	    	 		if ( index < 0 ) 
    	 			{
	    	 		   alert('Can not find card to attack:' + card.attackCard);	
	    	 		   return;
    	 			}
	    	 		cards.splice(index, 1);
	    	 		players[attacker] = cards;			    	 		 
	    	 		if ( attacker == 0 ) human = players[attacker]; else computer = players[attacker];
	    	 		$('#'+card.attackCard).remove();
	    	 		
	    	 		rounds = card.rounds;
	    	 		var newCard = createCard(card.attackCard, true);
	    	 		var left = desk[attacker].left + rounds * 90;
	    	 		newCard.css({"left":left+'px' ,'top':desk[attacker].top+'px'}).appendTo('#desk');
	    	 		cardsDefendable = card.cardsDefendable;
	    	 		tryDefend( (attacker+1) % 2, card.attackCard);	
	    	 		return;
    	 		}
	    	 	if ( card.attackCard == -2 )
    	 		{
	    	 		// attack manually
	    	 		cardsAttackable = card.cardsAttackable;
	    	 		humanAttack = true;
	    	 		if ( rounds > 0 ) $('#endAttack').show();
	    	 		return;
    	 		}
	    	 	
	    	 	// No card can attack or stop attack directly 
	    	 	if ( card.attackCard == 0 || card.attackCard == -1)
    	 		{
	    	 		endAttack(attacker);
    	 		}
     		 }
		 });
		 
	 }
	 
	 function tryDefend(defender, attackCard)
	 {
		 $.ajax({
	         url : "/durak/tryDefend",
		     type: "POST",
		     dataType : "json",
		     data : { defender: defender, attackCard: attackCard},
		     success: function (card){
		    	 	if ( card.defendCard > 0 )
	    	 		{ // defend automatically
		    	 		var players = [human, computer];			    	 		
		    	 		var cards = players[defender];
		    	 		var index = $.inArray(card.defendCard, cards );
		    	 		if ( index < 0 ) 
	    	 			{
		    	 		   alert('Can not find card to defend:' + card.defendCard);	
		    	 		   return;
	    	 			}
		    	 		cards.splice(index, 1);
		    	 		players[defender] = cards;			    	 		 
		    	 		if ( defender == 0 ) human = players[0]; else computer = players[1];
		    	 		$('#'+card.defendCard).remove();
		    	 		
		    	 		var newCard = createCard(card.defendCard, true);
		    	 		var left = desk[defender].left + rounds * 90;
		    	 		newCard.css({"left":left+'px' ,'top':desk[defender].top+'px'}).appendTo('#desk');
		    	 		rounds = card.rounds;		    	 		
		    	 		tryAttack( (defender+1) % 2);		    	 			
		    	 		return;
	    	 		}
		    	 	
		    	 	humanAttack = false;
		    	 	if ( card.defendCard == -2 )
	    	 		{
		    	 		// defend manually.
		    	 		cardsDefendable = card.cardsDefendable;
			    	 	$('#accept').show();		    	 		
	    	 		}
		    	 	
		    	 	if ( card.defendCard == -1 )
	    	 		{
		    	 		// have to accept cards.		    	 		
		    	 		cardsDefendable = [];
		    	 		checkAutoAccept(defender);
	    	 		}
		    	}});
	 }
	 
	 function endAttack(attacker)
	 {
		 $.ajax({
	         url : "/durak/endAttack",
 		     type: "POST",
 		     dataType : "json",
 		     data : { attacker: attacker },	 		     
 		     success: function (data){
	 		    	rounds = 0;
	 		    	$('#desk').empty();
	 	    		updateCards( human, 10, 30, '#humanPlayer', data.humanByValue ,data.humanBySuit,true,true);
		    		updateCards( computer, 10, 30, '#computerPlayer', data.computerByValue ,data.computerBySuit,showCard,true);
		    		$('.button').hide();
		    		tryAttack(data.attacker);
		    	 }
			 });
	 }
	 
	 function checkAutoAccept(defender)
	 {
		 $.ajax({
	         url : "/durak/checkAutoAccept",
 		     type: "POST",
 		     dataType : "json",
 		     data : { defender: defender },	 		     
 		     success: function (data){
 		    	 	if (data) 
	    	 		{
 		    	 		accept(defender);
	    	 		}
 		    	 	else
	    	 		{
			    	 	$('#accept').show();
	    	 		}
		    	 }
			 });
	 }
	 
	 
	 function accept(defender)
	 {
		 $.ajax({
	         url : "/durak/accept",
 		     type: "POST",
 		     dataType : "json",
 		     data : { defender: defender },	 		     
 		     success: function (data){
	 		    	rounds = 0;
	 		    	$('#desk').empty();
	 	    		updateCards( human, 10, 30, '#humanPlayer', data.humanByValue, data.humanBySuit, true,defender!=0);
		    		updateCards( computer, 10, 30, '#computerPlayer', data.computerByValue, data.computerBySuit, showCard,defender!=1);
		    		$('.button').hide();
		    		tryAttack(data.attacker);
		    	 }
			 });
	 }
});